package com.xu.sso.client.filter;

import com.xu.sso.client.config.SSOConfig;
import com.xu.sso.client.model.AppPathRole;
import com.xu.sso.client.model.UserLoginInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component
@Order(2)
public class PowerFilter extends GenericFilterBean {

    @Value("${com.xu.sso.app_id}")
    private String appId;

    private PathMatcher pathMatcher;

    @Override
    public void initFilterBean() throws ServletException {
        pathMatcher = new AntPathMatcher();
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String servletPath = request.getServletPath();

        long authCount = LoginFilter.authUrl.stream().filter(u -> pathMatcher.match(u, servletPath)).count();
        long staticCount = 0;
        if (authCount == 0) {
            staticCount = LoginFilter.staticUrl.stream().filter(u -> pathMatcher.match(u, servletPath)).count();
        }

        if (authCount > 0 || staticCount == 0) {
            UserLoginInfo userLoginInfo = (UserLoginInfo) request.getAttribute(SSOConfig.SSO_USER);
            // 验证操作权限
            List<String> userRoles = userLoginInfo.getAppRoles().get(appId);
            for (AppPathRole pathRole : LoginFilter.pathRoles) {
                if (!pathRole.isLogin()) {
                    continue;
                }
                boolean check = false;
                if (pathMatcher.match(pathRole.getPath(), servletPath)) {
                    check = true;
                }
                if (check && null != pathRole.getRoles() && pathRole.getRoles().size() > 0) {
                    Set<String> roles = new HashSet<>();
                    roles.addAll(userRoles);
                    roles.addAll(pathRole.getRoles());
                    if (roles.size() == (userRoles.size() + pathRole.getRoles().size())) {
                        String requestType = request.getHeader("X-Requested-With");
                        response.setCharacterEncoding("utf-8");
                        if (SSOConfig.AJAX_REQ.equalsIgnoreCase(requestType)) {
                            // 无访问权限
//                            response.sendError(HttpServletResponse.SC_FORBIDDEN, "无访问权限");
                            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                            response.setContentType("text/html;charset=utf-8;");
                            response.getWriter().println("无访问权限");
                            return;
                        } else {
                            // 无访问权限
                            response.setContentType("text/html;charset=utf-8;");
                            response.getWriter().println("<script>alert('无访问权限');window.history.go(-1);</script>");
                            return;
                        }
                    }
                }
            }
        }
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}
